﻿
// DntDemoDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "DntDemo.h"
#include "DntDemoDlg.h"
#include "afxdialogex.h"
#include "DntTest.h"
#include "TxtUtils.h"
#define TAG	"DntDlg"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif



CEdit* mLogView;
CDntDemoDlg* mDntDemoDlg;
CTabDdns* mTabDdns;
CTabDevice* mTabDevice;
CTabControl* mTabControl;
CTabAudioKc3x* mTabAudioKc3x;
CTabMusicPlayer* mTabMusicPlayer;

uint32_t gTxCount;
uint32_t gTxBytes;
uint32_t gRxCount;
uint32_t gRxBytes;

extern "C" void ShowLogView(char* text) {
	if (mLogView != NULL) {
		CString string(text);
		mLogView->SetSel(-1, -1);							// 插入光标放于最后
		mLogView->ReplaceSel(string);
		mLogView->ScrollWindow(0, 0);						// 滚动到插入点
	}
}
extern "C" void ShowHookCmd(uint8_t * inDat, int length, bool isTx) {
	char bytes[1024] = { 0 };
	memcpy(bytes, inDat, length);
	if (mTabDdns != NULL) {
		mTabDdns->ShowHookCmd(bytes, isTx);
	}
	if (isTx) {
		gTxCount += 1;
		gTxBytes += length;
	}
	else {
		gRxCount += 1;
		gRxBytes += length;
	}
	if (mDntDemoDlg != NULL) {
		mDntDemoDlg->ShowTitle();
	}
}
extern "C" static void dnIpLinkCallback() {
	if (mDntDemoDlg != NULL) {
		mDntDemoDlg->ShowComboServer(false);
	}
}


// CDntDemoDlg 对话框



CDntDemoDlg::CDntDemoDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DNTDEMO_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDntDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CDntDemoDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_CBN_SELCHANGE(IDC_COMBO_ROLE, OnSelchangeComboRole)
	ON_CBN_SELCHANGE(IDC_COMBO_SERVER, OnSelchangeComboServer)
	ON_BN_CLICKED(IDC_BUTTON_CLR, &CDntDemoDlg::OnBnClickedButtonClr)
	ON_BN_CLICKED(IDC_BUTTON_PAUSE, &CDntDemoDlg::OnBnClickedButtonPause)
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CDntDemoDlg 消息处理程序

BOOL CDntDemoDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	mLogView = (CEdit*)GetDlgItem(IDC_EDIT1);
	gTxCount = 0;
	gTxBytes = 0;
	gRxCount = 0;
	gRxBytes = 0;
	ShowTitle();
	TestInit();
	TestStart();
	CString string[] = { L"动态域名功能演示", L"电器设备端功能演示", L"控制端功能演示", L"控制端 Kc3x多声道功放", L"控制端 Kc3x网络音频播放器" };
	for (int index = 0; index < 5; index++) {
		((CComboBox*)GetDlgItem(IDC_COMBO_ROLE))->AddString(string[index]);
	}
	((CComboBox*)GetDlgItem(IDC_COMBO_ROLE))->SetCurSel(DbsGetMemValue("tab"));
	OnSelchangeComboRole();

	mDntDemoDlg = this;

	TestDnIpLinkCallback(dnIpLinkCallback);
	SetTimer(1, 100, NULL);
	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CDntDemoDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDntDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CDntDemoDlg::OnTimer(UINT_PTR nIDEvent) {
	CDialogEx::OnTimer(nIDEvent);
	ShowComboServer(true);
	KillTimer(1);											// SetTimer(1, 100, NULL);
}

void CDntDemoDlg::ShowComboServer(bool poweron) {
	CComboBox* combo = (CComboBox*)GetDlgItem(IDC_COMBO_SERVER);
	combo->ResetContent();
	
	//char bytes[128];
	DNT_INFO* dnti = DntGetInfo();
	int number = dnti->SvrDnStep / 4;
	//if (dnti->DnIpOk) {										// 已经获取到云控域名服务器
	//	uint8_t* ip = (uint8_t*)&dnti->SvrIpv4;				// 服务器的IP地址
	//	int length = TxtFormat(bytes, sizeof(bytes), "%d.%d.%d.%d:%d] ", ip[0], ip[1], ip[2], ip[3], dnti->SvrPort);
	//	if (dnti->LoginOk) {
	//		TxtStrCpy(bytes + length, sizeof(bytes) - length, "已登录");
	//	}else {
	//		TxtFormat(bytes + length, sizeof(bytes) - length, "未登录(重试%d)", dnti->SvrDnStep);
	//	}
	//}else {													// 还没有获取到云控域名服务器
	//	TxtFormat(bytes, sizeof(bytes), "正在获取域名IP] 未登录");
	//}
	CLOGE(TAG, "svrCb Error TTTT (%d)(%d)(%d)", dnti->LoginOk, dnti->DnIpOk, dnti->AccountErr);
	if (dnti->LoginOk && !dnti->AccountErr) {		// 已经登录云控域名服务器
		((CStatic*)GetDlgItem(IDC_LOGIN_STATUS_TEXT))->SetWindowText(L"账号状态：已登录");
	}
	else {
		if (dnti->AccountErr) {		// 登录出错
			((CStatic*)GetDlgItem(IDC_LOGIN_STATUS_TEXT))->SetWindowText(L"账号状态：账号出错");
		}
		else {
			((CStatic*)GetDlgItem(IDC_LOGIN_STATUS_TEXT))->SetWindowText(L"账号状态：未登录");
		}
	}

	//CLOGD(TAG, "Show ComboServer SvrDnStep %d %d %d %d", dnti->SvrDnStep, dnti->DnIpOk, dnti->LinkOk, dnti->LoginOk);
	CString string;// (bytes);
	char svrText[sizeof(DNT_SERVER)];
	memcpy(svrText, DNT_SERVER, sizeof(DNT_SERVER));
	char* array[256];
	int qty = TxtKeyArray((size_t*)array, svrText, sizeof(DNT_SERVER) - 1, '&', 1);
	for (int index = 0; index < (qty + 1); index++) {
		if (index > 0) {
			int select = index - 1;
			WCHAR name[32];
			TxtGbkUnicode((char*)name, sizeof(name), array[select]);
			CString server;
			if (select == number) {
				server.Format(L"%s %s", name, string);
				((CComboBox*)GetDlgItem(IDC_COMBO_SERVER))->AddString(server);// name + L" [" + string);
			}else {
				server.Format(L"固定#%d服务器%s (测试用 重试%d)", index, name, dnti->SvrDnStep);
				((CComboBox*)GetDlgItem(IDC_COMBO_SERVER))->AddString(server);
			}
		}else {
			CString server(array[number]);
			CString text;
			text.Format(L"自动 %d[%s/%s", dnti->SvrDnStep, server, string);
			((CComboBox*)GetDlgItem(IDC_COMBO_SERVER))->AddString(text);
		}
	}
	combo->SetCurSel(dnti->SvrFixed);
	ShowTips();
}
void CDntDemoDlg::ShowTitle() {
	char version[32];
	char bytes[128];
	DntVersion(version, sizeof(version));

	int length = TxtFormat(bytes, sizeof(bytes), "云控域名 开发包V%s.1", version);
	if (gRxCount > 0) {
		length += TxtFormat(bytes + length, 64, "        共发送%d次，%d字节。接收%d次，%d字节", gTxCount, gTxBytes, gRxCount, gRxBytes);
	}
	CString string(bytes);
	SetWindowText(string);
}
void CDntDemoDlg::ShowTips() {
	DNT_INFO* dnti = DntGetInfo();
	if (dnti != NULL) {
		char bytes[512];
		WCHAR word[512 * 2];
		int length = TxtStrCpy(bytes, sizeof(bytes), "\r\n*** 请使用CloudLog显示日志 ***\r\nDntSdk\\PlatformWindows\\CloudLog.exe\r\n");
		int number = dnti->SvrDnStep / 4;
		if (dnti->DnIpOk) {										// 已经获取到云控域名服务器
			uint8_t* ip = (uint8_t*)&dnti->SvrIpv4;				// 服务器的IP地址
//			int length = TxtFormat(bytes, sizeof(bytes), "%d.%d.%d.%d:%d] ", ip[0], ip[1], ip[2], ip[3], dnti->SvrPort);
			if (dnti->LoginOk) {
				length += TxtFormat(bytes + length, sizeof(bytes) - length, "已登录[%d.%d.%d.%d:%d]", ip[0], ip[1], ip[2], ip[3], dnti->SvrPort);
			}else {
				length += TxtFormat(bytes + length, sizeof(bytes) - length, "未登录 (重试%d)", dnti->SvrDnStep);
			}
		}else {													// 还没有获取到云控域名服务器
			length += TxtStrCpy(bytes, sizeof(bytes), "未登录 (正在获取域名IP)");
		}
		TxtGbkUnicode((char*)word, sizeof(word), bytes);
		((CStatic*)GetDlgItem(IDC_STATIC_TIPS))->SetWindowText(word);
	}
}
void CDntDemoDlg::ShowTips(int index) {
	char name[64];
	char group[64];
	char ipv4[32];
	char bytes[512];
	int length = 0;
	switch (index) {
	case 0:
		DbsGetMemText(name, sizeof(name), "an_0");
		DbsGetMemText(ipv4, sizeof(ipv4), "ipv4");
		if (name[0] != 0) {
			length = TxtFormat(bytes, sizeof(bytes), "当前使用的域名账号为%s，通过动态解析的本机的IP地址，其他电脑、手机或电器设备就能通过%s", name, name);
			length += TxtFormat(bytes + length, sizeof(bytes) - length, "访问本电脑或者本地网络的手机或其他电器设备。当前本地网络IP地址为%s", ipv4);
		}
		else {
			length = TxtFormat(bytes, sizeof(bytes), "动态域名可以申请一个固定域名的账号例如8888.ip71.cn，其他电脑、手机或电器设备就能通过8888.ip71.cn");
			length += TxtFormat(bytes + length, sizeof(bytes) - length, "访问本电脑或者本地网络的手机或其他电器设备。\r\n");
			length += TxtFormat(bytes + length, sizeof(bytes) - length, "角色选择为电器设备端可以建立一个群，拉一堆控制端相互通讯");
		}
		break;
	case 1:
		DbsGetMemText(group, sizeof(group), "an_1");
		if (group[0] != 0) {
			length = TxtFormat(bytes, sizeof(bytes), "电器设备端与多个控制端在%s群里，群主为电器设备端。群主家里有一块寄存器，", group);
		}
		else {
			length = TxtFormat(bytes, sizeof(bytes), "电器设备端与多个控制端在同一个群，群主为电器设备端。群主家里有一块寄存器，");
		}
		length += TxtFormat(bytes + length, sizeof(bytes) - length, "各个群成员都可以修改寄存器的值，服务器会将修改的值同步到所有群成员，");
		length += TxtFormat(bytes + length, sizeof(bytes) - length, "这样就实现可以电脑、手机及电器设备的远程控制。");
		break;
	case 2:
		DbsGetMemText(name, sizeof(name), "an_1");
		DbsGetMemText(group, sizeof(group), "an_1");
		if (name[0] != 0) {
			length = TxtFormat(bytes, sizeof(bytes), "%s控制端已在加入到%s群里，", name, group);
		}
		else {
			length = TxtFormat(bytes, sizeof(bytes), "可以加入到电器设备端群");
		}
		length += TxtFormat(bytes + length, sizeof(bytes) - length, "各个群成员都可以修改群寄存器的值，服务器会将修改的值同步到所有群成员，");
		length += TxtFormat(bytes + length, sizeof(bytes) - length, "这样就实现可以电脑、手机及电器设备的远程控制。");
		break;
	case 3:
		length = TxtFormat(bytes, sizeof(bytes), "可以加入到电器设备端群");
		break;
	}
	bytes[length] = 0;
	WCHAR word[512 * 2];
	TxtGbkUnicode((char*)word, sizeof(word), bytes);
	((CStatic*)GetDlgItem(IDC_EDIT_TIPS))->SetWindowText(word);
	ShowTips();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CDntDemoDlg::PreTranslateMessage(MSG* pMsg) {
	if (pMsg->message == WM_KEYDOWN) {
		if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN) {
			return 1;
		}
	}
	return CDialog::PreTranslateMessage(pMsg);
}

void CDntDemoDlg::OnSelchangeComboRole() {				// 功能角色选择
	TestLoginOkCallback(NULL);
	TestChangRegCallback(NULL);
	if (mTabDdns != NULL) {
		delete mTabDdns;
		mTabDdns = NULL;
	}
	if (mTabDevice != NULL) {
		delete mTabDevice;
		mTabDevice = NULL;
	}
	if (mTabControl != NULL) {
		delete mTabControl;
		mTabControl = NULL;
	}
	if (mTabAudioKc3x != NULL) {
		delete mTabAudioKc3x;
		mTabAudioKc3x = NULL;
	}
	if (mTabMusicPlayer != NULL) {
		delete mTabMusicPlayer;
		mTabMusicPlayer = NULL;
	}
	int index = ((CComboBox*)GetDlgItem(IDC_COMBO_ROLE))->GetCurSel();
	CRect rect;
	GetClientRect(&rect); //得到Tabcontrol控件的大小，为后面显示Dlg1和Dlg2的位置和大小
	int moveX = 330;
	switch (index) {
	case 0:
		mTabDdns = new CTabDdns();
		mTabDdns->Create(IDD_TAB_DDNS, GetOwner());
		mTabDdns->SetWindowPos(NULL, moveX, 10, rect.right - 10, rect.bottom - 10, SWP_SHOWWINDOW);

		DbsSetMemValue("device", 0);
		DbsSetMemValue("control", 0);
		break;
	case 1:
		mTabDevice = new CTabDevice();
		mTabDevice->Create(IDD_TAB_DEVICE, GetOwner());
		mTabDevice->SetWindowPos(NULL, moveX, 10, rect.right - 10, rect.bottom - 10, SWP_SHOWWINDOW);
		DbsSetMemValue("device", 1);
		DbsSetMemValue("control", 0);
		break;
	case 2:
		mTabControl = new CTabControl();
		mTabControl->Create(IDD_TAB_CONTROL, GetOwner());
		mTabControl->SetWindowPos(NULL, moveX, 10, rect.right - 10, rect.bottom - 10, SWP_SHOWWINDOW);
		DbsSetMemValue("device", 0);
		DbsSetMemValue("control", 1);
		break;
	case 3:
		mTabAudioKc3x = new CTabAudioKc3x();
		mTabAudioKc3x->Create(IDD_TAB_AUDIO_KC3X, GetOwner());
		mTabAudioKc3x->SetWindowPos(NULL, moveX, 10, rect.right - 10, rect.bottom - 10, SWP_SHOWWINDOW);
		DbsSetMemValue("device", 0);
		DbsSetMemValue("control", 1);
		break;
	case 4:
		mTabMusicPlayer = new CTabMusicPlayer();
		mTabMusicPlayer->Create(IDD_TAB_MUSIC_PLAYER, GetOwner());
		mTabMusicPlayer->SetWindowPos(NULL, moveX, 10, rect.right - 10, rect.bottom - 10, SWP_SHOWWINDOW);
		DbsSetMemValue("device", 0);
		DbsSetMemValue("control", 1);
		break;
	}
	DbsSetMemValue("tab", index);
	ShowTips(index);
}
void CDntDemoDlg::OnSelchangeComboServer() {				// 服务器 状态
	DNT_INFO* dnti = DntGetInfo();
	dnti->SvrFixed = ((CComboBox*)GetDlgItem(IDC_COMBO_SERVER))->GetCurSel();
	DbsSetMemValue("svrFixed", dnti->SvrFixed);
	DntSetIdleFlag(DNT_RB_SVR_DN_IP);
}
void CDntDemoDlg::OnBnClickedButtonClr() {
	mLogView->SetWindowText(L"");
}
void dnipCallback(uint32_t* ipv4s, int length) {
	uint8_t* ip = (uint8_t*)(ipv4s + 0);
	CLOGD(TAG, "dnipCall length:%d %d.%d.%d.%d", length, ip[0], ip[1], ip[2], ip[3]);
	if (length > 1) {
		ip = (uint8_t*)(ipv4s + 1);
		CLOGD(TAG, "dnipCall A %d %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
		if (length > 2) {
			ip = (uint8_t*)(ipv4s + 2);
			CLOGD(TAG, "dnipCall B %d %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
			if (length > 3) {
				ip = (uint8_t*)(ipv4s + 3);
				CLOGD(TAG, "dnipCall C %d %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
			}
		}
	}
}
void CDntDemoDlg::OnBnClickedButtonPause() {
	CLOGD(TAG, "ButtonPause A");
	/*if (!DntSetIdleFlag(DNT_RB_USER_DN_IP)) {
		::AfxMessageBox(L"出错：上一个还没有完成或者网络出错");
	}*/
	//DntGetDnIp("hsav.com", dnipCallback);
}




